package com.sora.sora.common.config;

import com.sora.sora.common.annotation.Auth;
import com.sora.sora.security.authorise.model.entity.Resources;
import com.sora.sora.security.authorise.service.ResourcesService;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Component
public class ApplicationStartUp implements ApplicationRunner {

    @Resource
    RequestMappingInfoHandlerMapping requestMappingInfoHandlerMapping;
    @Resource
    ResourcesService resourcesService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 扫描获取所有需要权限赋值的接口
        List<Resources> list = this.getAuthResources();
        resourcesService.delResourcesByType(1);
        if (list.isEmpty()) {
            return;
        }
        resourcesService.addResouces(list);
    }

    // 扫描所有需要权限处理的接口资源
    private List<Resources> getAuthResources() {
        List<Resources> list = new LinkedList<>();
        // 拿到接口信息
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingInfoHandlerMapping.getHandlerMethods();
        // 开始遍历
        handlerMethods.forEach((info, handlerMethod) -> {
            // 拿到类上的注解
            Auth modulAuth = handlerMethod.getBeanType().getAnnotation(Auth.class);
            // 拿到方法上的注解
            Auth methodAuth = handlerMethod.getMethod().getAnnotation(Auth.class);
            // 类和方法上的注解缺一个都不进行处理
            if (modulAuth == null || methodAuth == null) {
                return;
            }
            // 拿到请求方式，如post,get
            Set<RequestMethod> methods = info.getMethodsCondition().getMethods();
            if (methods.size() != 1) {
                return;
            }
            String path = methods.toArray()[0] + ":" + info.getPatternsCondition().getPatterns().toArray()[0];
            Resources resources = new Resources();
            resources.setId(modulAuth.id() + methodAuth.id());
            resources.setName(methodAuth.name());
            resources.setPath(path);
            resources.setType(1);
            list.add(resources);
        });
        return list;
    }
}
